package com.gitee.fsmxm.thinking.in.concurrent.basic;

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.StampedLock;

/**
 * ReentrantLock可重入互斥锁，和隐式锁synchronized相当（行为和语义），但有扩展功能
 * <p>如：tryLock(), lockInterruptibly()
 */
public class _05_ReentrantLock {

    // 可重入锁 和 不可重入锁
    public static class ReentrantLockDemo {
        ReentrantLock reentrantLock = new ReentrantLock();
        StampedLock stampedLock = new StampedLock();

        public void doReentrantLock1() {
            reentrantLock.lock();
            try {
                doReentrantLock2();
            } finally {
                reentrantLock.unlock();
            }
        }

        public void doReentrantLock2() {
            reentrantLock.lock();
            try {
                System.out.println("lock in lock");
            } finally {
                reentrantLock.unlock();
            }
        }

        public void doStampedLock1() {
            long l = stampedLock.writeLock();
            try {
                doStampedLock2();
            } finally {
                stampedLock.unlockWrite(l);
            }
        }

        public void doStampedLock2() {
            long l = stampedLock.readLock(); // 不可重入
//            long l = stampedLock.tryOptimisticRead(); // 乐观读
            try {
                System.out.println("lock in lock");
            } finally {
                stampedLock.unlockRead(l);
            }
        }

        public static void main(String[] args) throws InterruptedException {
            ReentrantLockDemo demo = new ReentrantLockDemo();
            Thread t1 = new Thread(demo::doReentrantLock1, "t1");
            Thread t2 = new Thread(demo::doStampedLock1, "t2");

            t1.start();
            t2.start();

            t1.join();
            t2.join();
        }


    }

}
